package qtdz9;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class World extends JPanel {
    public static final int WIDTH = 641;
    public static final int HEIGHT = 479;

    public static final int RUNNING = 0;//运行状态
    public static final int PAUSE = 1; //暂停状态
    public static final int GAME_OVER = 2;//游戏结束
    private int state = RUNNING;//当前状态默认运行
    //private Battleship ship = new Battleship();
    //private SeaObject[] submarine ={new MineSubmarine(),
    //new ObserveSubmarine(),new TorpedoSubmarine()};
    //private Bomb[] bomb = {new Bomb(100,200)};
    //private Mine[] mine = {new Mine(120,120)};

    private Battleship ship = new Battleship();
    private SeaObject[] submarines = {};
    private Bomb[] bombs = {};
    private Mine[] mines = {};

    //生成潜艇对象
    private SeaObject nextSubmarine() {
        Random rand = new Random();
        int type = rand.nextInt(20);
        if (type < 10) {
            return new ObserveSubmarine();
        } else if (type < 16) {
            return new TorpedoSubmarine();
        } else {
            return new MineSubmarine();
        }
    }

    //潜艇入场
    private int subEnterIndex = 0;//潜艇的进场计数
    private void submarineEnterAction() {//每10毫秒走一次
        subEnterIndex++;//每10毫秒增1
        if (subEnterIndex % 40 == 0) {
            SeaObject obj = nextSubmarine();
            submarines = Arrays.copyOf(submarines, submarines.length + 1);
            submarines[submarines.length - 1] = obj;
        }
    }

    //水雷入场
    private int mineEnterindex = 0;

    private void mineEnterAction() {
        mineEnterindex++;
        if (mineEnterindex % 100 == 0) {
            for (int i = 0; i < submarines.length; i++) {
                if (submarines[i] instanceof MineSubmarine) {
                    MineSubmarine ms = (MineSubmarine) submarines[i];
                    Mine obj = ms.shootMine();
                    mines = Arrays.copyOf(mines, mines.length + 1);
                    mines[mines.length - 1] = obj;
                }
            }
        }
    }

    //海洋对象移动
    private void moveAction() {
        for (int i = 0; i < submarines.length; i++) {
            submarines[i].move();
        }
        for (int i = 0; i < mines.length; i++) {
            mines[i].move();
        }
        for (int i = 0; i < bombs.length; i++) {
            bombs[i].move();
        }
    }

    //删除越界对象
    private void outOfBoundsAction() {
        for (int i = 0; i < submarines.length; i++) {
            if (submarines[i].isOutOfBounds()) {
                submarines[submarines.length - 1] = submarines[i];
                submarines = Arrays.copyOf(submarines, submarines.length - 1);
            }
        }
        for (int i = 0; i < mines.length; i++) {
            if (mines[i].isOutOfBounds()) {
                mines[mines.length - 1] = mines[i];
                mines = Arrays.copyOf(mines, mines.length - 1);
            }
        }
        for (int i = 0; i < bombs.length; i++) {
            if (bombs[i].isOutOfBounds()) {
                bombs[bombs.length - 1] = bombs[i];
                bombs = Arrays.copyOf(bombs, bombs.length - 1);
            }
        }
    }

    //炸弹与潜艇碰撞
    private int score = 0;

    private void bombBangAction() {
        for (int i = 0; i < bombs.length; i++) {
            Bomb b = bombs[i];
            for (int j = 0; j < submarines.length; j++) {
                SeaObject s = submarines[j];
                if (b.isLive() && s.isLive() && b.isHit(s)) {
                    s.goDead();
                    b.goDead();
                    if (s instanceof EnemyScore) {
                        EnemyScore es = (EnemyScore) s;
                        score += es.getScore();//
                    }
                    if (s instanceof EnemyLife) {
                        EnemyLife el = (EnemyLife) s;
                        int num = el.getLife();
                        ship.addLife(num);
                    }
                }
            }
        }
    }

    //水雷与战舰的碰撞
    private void mineBangAction() {
        for (int i = 0; i < mines.length; i++) {
            Mine m = mines[i];
            if (m.isLive() && ship.isLive() && m.isHit(ship)) {
                m.goDead();
                ship.subtractLife();
            }
        }
    }

    //检测游戏结束
    private void checkGameOverAction() {
        if (ship.getLife() <= 0) {
            state = GAME_OVER;
        }
    }

    //启动程序的执行
    void action() {
        //键盘侦听器---不要求掌握
        KeyAdapter k = new KeyAdapter() {
            //重写keyReleased()按键抬起事件,keyPressed()按键按下事件
            public void keyReleased(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_P) {
                    if (state == RUNNING) {
                        state = PAUSE;
                    } else if (state == PAUSE) {
                        state = RUNNING;
                    }
                }
                if (state == RUNNING) {
                    if (e.getKeyCode() == KeyEvent.VK_SPACE) {//若抬起的是空格键
                        Bomb obj = ship.shootBomb();
                        bombs = Arrays.copyOf(bombs, bombs.length + 1);
                        bombs[bombs.length - 1] = obj;
                    }
                    if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                        ship.moveLeft();
                    }
                    if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                        ship.moveRight();
                    }
                }
            }
        };
        this.addKeyListener(k);//添加侦查

        Timer timer = new Timer();
        int interval = 10;
        timer.schedule(new TimerTask() {
            public void run() {
                if(state==RUNNING) {
                    submarineEnterAction();
                    mineEnterAction();
                    moveAction();
                    bombBangAction();
                    mineBangAction();
                    outOfBoundsAction();
                    checkGameOverAction();
                    repaint();//重画(自动调用paint()方法)
                }
            }
        }, interval, interval);
    }

    //重写paint()方法 g:画笔
    public void paint(Graphics g) {
        Images.sea.paintIcon(null, g, 0, 0);
        ship.paintImage(g);
        for (int i = 0; i < submarines.length; i++) {
            submarines[i].paintImage(g);
        }
        for (int i = 0; i < bombs.length; i++) {
            bombs[i].paintImage(g);
        }
        for (int i = 0; i < mines.length; i++) {
            mines[i].paintImage(g);
        }
        g.drawString("SCORE:" + score, 150, 70);
        g.drawString("LIFE:" + ship.getLife(), 400, 70);

        if (state == GAME_OVER) {
            Images.gameover.paintIcon(null, g, 0, 0);
        }
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        World world = new World();
        world.setFocusable(true);
        frame.add(world);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH + 16, HEIGHT + 39);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setVisible(true);

        world.action();
    }

    /*
    public static void main(String[] args) {

        SeaObject[] submarine = new SeaObject[6];
        submarine[0]=new MineSubmarine();
        submarine[1]=new MineSubmarine();
        submarine[2]=new ObserveSubmarine();
        submarine[3]=new ObserveSubmarine();
        submarine[4]=new TorpedoSubmarine();
        submarine[5]=new TorpedoSubmarine();
        for(int i=0;i<submarine.length;i++){
            submarine[i].move();
        }
        Mine[] mine = new Mine[3];
        mine[0]=new Mine(100,220);
        mine[1]=new Mine(120,120);
        mine[2]=new Mine(150,150);
        for(int i=0;i<mine.length;i++){
            mine[i].move();
        }
        Bomb[] bomb = new Bomb[3];
        bomb[0]=new Bomb(100,123);
        bomb[1]=new Bomb(150,200);
        bomb[2]=new Bomb(200,250);
        for(int i=0;i<bomb.length;i++){
            bomb[i].move();
        }
    }
     */
}
